﻿using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Thrift;
using Thrift.Protocols;
using Thrift.Server;
using Thrift.Transports;
using Thrift.Transports.Server;

namespace M.Core
{
    // 服务端初始化启动Thrift Rpc服务
    public static class ServiceExtensions
    {

        public class MyServerEventHandler : TServerEventHandler
        {
            public int callCount = 0;

            public Task PreServeAsync(CancellationToken cancellationToken)
            {
                callCount++;
                return Task.CompletedTask;
            }

            public Task<object> CreateContextAsync(TProtocol input, TProtocol output, CancellationToken cancellationToken)
            {
                callCount++;
                return Task.FromResult<object>(null);
            }

            public Task DeleteContextAsync(object serverContext, TProtocol input, TProtocol output, CancellationToken cancellationToken)
            {
                callCount++;
                return Task.CompletedTask;
            }

            public Task ProcessContextAsync(object serverContext, TClientTransport transport, CancellationToken cancellationToken)
            {
                callCount++;
                return Task.CompletedTask;
            }
        }

        //初始化Thrift服务
        public static IApplicationBuilder UseThriftService(this IApplicationBuilder builder, int ThriftPort, Action<TMultiplexedProcessor> processContent)
        {
            var logger = builder.ApplicationServices.GetService<ILogger<TMultiplexedProcessor>>();

            var multiplexed = new TMultiplexedProcessor();

            processContent(multiplexed);

            ITProcessorFactory processorFactory = new SingletonTProcessorFactory(multiplexed);


            TTransportFactory transFactory = new TTransportFactory();
            ITProtocolFactory proto = new TBinaryProtocol.Factory();
            TServerTransport trans = new TServerFramedTransport(ThriftPort);
            TBaseServer serverEngine = new AsyncBaseServer(processorFactory, trans, transFactory, transFactory, proto, proto, logger);

            var serverEvents = new MyServerEventHandler();
            serverEngine.SetEventHandler(serverEvents);

            var services = builder.ApplicationServices.CreateScope().ServiceProvider;

            var lifeTime = services.GetService<IApplicationLifetime>();
            lifeTime.ApplicationStarted.Register(() =>
            {
                serverEngine.ServeAsync(CancellationToken.None).GetAwaiter().GetResult();
            });
            lifeTime.ApplicationStopped.Register(() =>
            {
                serverEngine.Stop();
            });


            return builder;
        }


  
    }
}
